
#ifndef SEMANTICS_MODEL_H

#define SEMANTICS_MODEL_H

#include "stdio.h"
#include "syntax_tree.h"
#include "generic_table.h"
#include "semantics_field.h"
#include "semantics_property.h"
#include "semantics_enum.h"


class SemanticsModelBodyDefine
{
public:
	SemanticsModelBodyDefine()
	{
		this->Enums = new GenericTable<SemanticsEnum>();
		this->Fields = new GenericTable<SemanticsField>();
		this->Methods = new GenericTable<SemanticsMethod>();
		this->Properties = new GenericTable<SemanticsProperty>();
	}


	~SemanticsModelBodyDefine()
	{
		if(Fields != NULL)
		{
			delete Fields;
			Fields = NULL;
		}

		if(Properties != NULL)
		{
			delete Properties;
			Properties = NULL;
		}

		if(Methods != NULL)
		{
			delete Methods;
			Methods = NULL;
		}

		if(Enums != NULL)
		{
			delete Enums;
			Enums = NULL;
		}
	}


#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	GenericTable<SemanticsField> * Fields;
	GenericTable<SemanticsProperty> * Properties;
	GenericTable<SemanticsEnum> * Enums;
	GenericTable<SemanticsMethod> * Methods;

};


enum SemanticsModelBlockType
{
	ModBlockGenerate,
	ModBlockTerminate,
	ModBlockAdvance,
	ModBlockEnter,
	ModBlockLeave,
	ModBlockSeize,
	ModBlockRelease,
	ModBlockInqueue,
	ModBlockOutqueue,
	ModBlockArrive,
	ModBlockDepart,
	ModBlockModelInstance,
	ModBlockGoto,
	ModBlockIf,
	ModBlockWait,
	ModBlockJoinGroup,
	ModBlockLeaveGroup,
	ModBlockCreate,
	ModBlockSplit,
	ModBlockGather,
	ModBlockExecute
};

class SemanticsModelBlock
{
public:
	SemanticsModelBlock()
	{
		//?? kako inicijalizirat enum
		//this->BlockType;
		this->Labels = new GenericTable<int>();
	}

	virtual ~SemanticsModelBlock()
	{
	}

#ifdef DEBUG

	void DebugXMLOutput(FILE * fo);    // mora biti u public dijelu

#endif

	SemanticsModelBlockType BlockType;

	GenericTable<int> * Labels;
};



class SemanticsModelStructure
{
public:
	SemanticsModelStructure()
	{
		this->Blocks = new GenericTable<SemanticsModelBlock>;
	}

	~SemanticsModelStructure()
	{
	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	GenericTable<SemanticsModelBlock> * Blocks;

};


// ALL MODEL BLOCKS

class SemanticsBlockTransactionDetail
{
public:
	SemanticsBlockTransactionDetail()
	{
		TransactionName = new GenericTable<int>();
		Expression = NULL;
	}

	~SemanticsBlockTransactionDetail()
	{
		delete TransactionName;
	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);    // mora biti u public dijelu
#endif

	GenericTable<int> * TransactionName;
	SemanticsExpression * Expression;

};


class SemanticsBlockGenerate : SemanticsModelBlock
{
public:
	SemanticsBlockGenerate():SemanticsModelBlock()
	{
		BlockType = ModBlockGenerate;
		UptoExpression = NULL;

		TransactionName = new GenericTable<int>();
		TransactionList = new GenericTable<SemanticsBlockTransactionDetail>();

		AfterExpression = NULL;
		EveryExpressionMean = NULL;
		EveryExpressionDeviation = NULL;
	}

	~SemanticsBlockGenerate()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * UptoExpression;
	GenericTable<int> * TransactionName;
	GenericTable<SemanticsBlockTransactionDetail> * TransactionList;

	SemanticsExpression * AfterExpression;
	SemanticsExpression * EveryExpressionMean;
	SemanticsExpression * EveryExpressionDeviation;
};


class SemanticsBlockTerminate : SemanticsModelBlock
{
public:
	SemanticsBlockTerminate():SemanticsModelBlock()
	{
		BlockType = ModBlockTerminate;
		Expression = NULL;
	}

	~SemanticsBlockTerminate()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
};


class SemanticsBlockAdvance : SemanticsModelBlock
{
public:
	SemanticsBlockAdvance():SemanticsModelBlock()
	{
		BlockType = ModBlockAdvance;
		ExpressionMean = NULL;
		ExpressionDeviation = NULL;
	}

	~SemanticsBlockAdvance()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * ExpressionMean;
	SemanticsExpression * ExpressionDeviation;
};



class SemanticsBlockEnter : SemanticsModelBlock
{
public:
	SemanticsBlockEnter():SemanticsModelBlock()
	{
		BlockType = ModBlockEnter;
		ExpressionUnitsIn = NULL;
		Expression = NULL;
		ExpressionForming = NULL;
	}

	~SemanticsBlockEnter()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * ExpressionUnitsIn;
	SemanticsExpression * Expression;
	SemanticsExpression * ExpressionForming;
};



class SemanticsBlockLeave : SemanticsModelBlock
{
public:
	SemanticsBlockLeave():SemanticsModelBlock()
	{
		BlockType = ModBlockLeave;
		ExpressionUnitsFrom = NULL;
		Expression = NULL;

	}

	~SemanticsBlockLeave()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * ExpressionUnitsFrom;
	SemanticsExpression * Expression;
};


class SemanticsBlockSeize : SemanticsModelBlock
{
public:
	SemanticsBlockSeize():SemanticsModelBlock()
	{
		BlockType = ModBlockSeize;
		Expression = NULL;
		ExpressionForming = NULL;
	}

	~SemanticsBlockSeize()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
	SemanticsExpression * ExpressionForming;
};



class SemanticsBlockRelease : SemanticsModelBlock
{
public:
	SemanticsBlockRelease():SemanticsModelBlock()
	{
		BlockType = ModBlockRelease;
		Expression = NULL;
	}

	~SemanticsBlockRelease()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
};




class SemanticsBlockInqueue : SemanticsModelBlock
{
public:
	SemanticsBlockInqueue():SemanticsModelBlock()
	{
		BlockType = ModBlockInqueue;
		Expression = NULL;
	}

	~SemanticsBlockInqueue()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
};



class SemanticsBlockOutqueue : SemanticsModelBlock
{
public:
	SemanticsBlockOutqueue():SemanticsModelBlock()
	{
		BlockType = ModBlockOutqueue;
		Expression = NULL;
	}

	~SemanticsBlockOutqueue()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
};



class SemanticsBlockArrive : SemanticsModelBlock
{
public:
	SemanticsBlockArrive():SemanticsModelBlock()
	{
		BlockType = ModBlockArrive;
		Expression = NULL;
	}

	~SemanticsBlockArrive()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
};



class SemanticsBlockDepart : SemanticsModelBlock
{
public:
	SemanticsBlockDepart():SemanticsModelBlock()
	{
		BlockType = ModBlockDepart;
		Expression = NULL;
	}

	~SemanticsBlockDepart()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
};




class SemanticsBlockModelInstance : SemanticsModelBlock
{
public:
	SemanticsBlockModelInstance():SemanticsModelBlock()
	{
		BlockType = ModBlockModelInstance;
		Name = new GenericTable<int>();
		Arguments = new GenericTable<SemanticsExpression>();
	}

	~SemanticsBlockModelInstance()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	GenericTable<int> * Name;
	GenericTable<SemanticsExpression> * Arguments;
};



class SemanticsBlockGoto : SemanticsModelBlock
{
public:
	SemanticsBlockGoto():SemanticsModelBlock()
	{
		BlockType = ModBlockGoto;
		Label = new GenericTable<int>();
	}

	~SemanticsBlockGoto()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	GenericTable<int> * Label;
};



class SemanticsBlockIf : SemanticsModelBlock
{
public:
	SemanticsBlockIf():SemanticsModelBlock()
	{
		BlockType = ModBlockIf;
		Expression = NULL;
		StructureIf = NULL;
		StructureElse = NULL;
	}

	~SemanticsBlockIf()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
	SemanticsModelStructure * StructureIf;
	SemanticsModelStructure * StructureElse;
};


enum SemanticsWaitType
{
	WaitWhile,
	WaitUntil
};


class SemanticsModelName
{
public:
	SemanticsModelName()
	{
	}

	~SemanticsModelName()
	{
	}

#ifdef DEBUG

	void DebugXMLOutput(FILE * fo);    // mora biti u public dijelu

#endif

	GenericTable<int> * Name;
};


class SemanticsBlockWait : SemanticsModelBlock
{
public:
	SemanticsBlockWait():SemanticsModelBlock()
	{
		BlockType = ModBlockWait;
		ExpressionForming = NULL;
		SensitivityList = new GenericTable<SemanticsModelName>();
		Type = WaitWhile;
		ExpressionWhileUntil = NULL;
		StructureThen = NULL;
		StructureElse = NULL;
		ExpressionTimeout = NULL;
		StructureTimeout = NULL;
	}

	~SemanticsBlockWait()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * ExpressionForming;

	GenericTable<SemanticsModelName> * SensitivityList;

	SemanticsWaitType Type;
	SemanticsExpression * ExpressionWhileUntil;


	SemanticsModelStructure * StructureThen;
	SemanticsModelStructure * StructureElse;

	SemanticsExpression * ExpressionTimeout;
	SemanticsModelStructure * StructureTimeout;
};


class SemanticsBlockJoinGroup : SemanticsModelBlock
{
public:
	SemanticsBlockJoinGroup():SemanticsModelBlock()
	{
		BlockType = ModBlockJoinGroup;
		Expression = NULL;
	}

	~SemanticsBlockJoinGroup()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
};


class SemanticsBlockLeaveGroup : SemanticsModelBlock
{
public:
	SemanticsBlockLeaveGroup():SemanticsModelBlock()
	{
		BlockType = ModBlockLeaveGroup;
		Expression = NULL;
	}

	~SemanticsBlockLeaveGroup()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * Expression;
};



class SemanticsBlockCreate : SemanticsModelBlock
{
public:
	SemanticsBlockCreate():SemanticsModelBlock()
	{
		BlockType = ModBlockCreate;
		UptoExpression = NULL;

		TransactionName = new GenericTable<int>();
		TransactionList = new GenericTable<SemanticsBlockTransactionDetail>();

		AfterExpression = NULL;
		EveryExpressionMean = NULL;
		EveryExpressionDeviation = NULL;

		SendToName = new GenericTable<int>(); 
	}

	~SemanticsBlockCreate()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * UptoExpression;

	GenericTable<int> * TransactionName;
	GenericTable<SemanticsBlockTransactionDetail> * TransactionList;

	SemanticsExpression * AfterExpression;
	SemanticsExpression * EveryExpressionMean;
	SemanticsExpression * EveryExpressionDeviation;

	GenericTable<int> * SendToName;
};



class SemanticsBlockSplit : SemanticsModelBlock
{
public:
	SemanticsBlockSplit():SemanticsModelBlock()
	{
		BlockType = ModBlockSplit;
		ExpressionInto = NULL;

		SendToName = new GenericTable<int>(); 
	}

	~SemanticsBlockSplit()
	{

	}

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif

	SemanticsExpression * ExpressionInto;
	GenericTable<int> * SendToName;
};



class SemanticsBlockGather : SemanticsModelBlock
{
public:
	SemanticsBlockGather():SemanticsModelBlock()
	{
		BlockType = ModBlockGather;
		Destroy = false;
		Expression = NULL;
	}

	~SemanticsBlockGather()
	{

	}

#ifdef DEBUG

	void DebugXMLOutput(FILE * fo);    // mora biti u public dijelu

#endif

	bool Destroy;
	SemanticsExpression * Expression;
};


class SemanticsBlockExecute : SemanticsModelBlock
{
public:
	SemanticsBlockExecute():SemanticsModelBlock()
	{
		BlockType = ModBlockExecute;
		Body = NULL;
	}

	~SemanticsBlockExecute()
	{

	}

#ifdef DEBUG

	void DebugXMLOutput(FILE * fo);    // mora biti u public dijelu

#endif

	SemanticsMethodBody * Body;
};



// MAIN CLASS

class SemanticsModel
{
public:
	SemanticsModel();
	~SemanticsModel();

	int CurrentContext;

	bool ModifierPrivate;
	bool ModifierPublic;

	bool HasDefaultInLabel;
	bool HasDefaultOutLabel;

	GenericTable<int> * Name;
	GenericTable<SemanticsMethodParameter> * Parameters;

	GenericTable<int> * LabelsIn;
	GenericTable<int> * LabelsOut;

	SemanticsModelBodyDefine * Definition;
	SemanticsModelStructure * Structure;

#ifdef DEBUG
	void DebugXMLOutput(FILE * fo);
#endif
};

#endif

